package com.jdone.compus.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jdone.compus.dto.SaasProperties;
import com.jdone.compus.model.User;
import com.jdone.compus.repository.UserRepository;
import com.jdone.compus.security.JwtTokenProvider;
import com.jdone.compus.utils.SignUtil;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.util.Collections;

@Service
@RequiredArgsConstructor
public class VerifyUserService {

    private static final Logger logger = LoggerFactory.getLogger(VerifyUserService.class);

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    @Autowired
    private SaasProperties props;

    private final UserRepository userRepository;
    private final JwtTokenProvider tokenProvider;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public String verifyUserAndIssueJwt(String token) {
        String body = callThirdPartyVerify(token);

        try {
            JsonNode root = objectMapper.readTree(body);
            int code = root.path("code").asInt(-1);
            String msg = root.path("msg").asText("");
            JsonNode data = root.path("data");
            String traceId = root.path("trace_id").asText(null); // 如果有的话

            if (code != 200) {
                throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "第三方校验失败: " + msg);
            }

            // 第三方校验通过——不管 data 中 username 是谁，都使用本地 admin 账户签发 token
            String adminUsername = "admin";

            User admin = userRepository.findByUsernameOrEmail(adminUsername, adminUsername)
                    .orElseThrow(() -> new IllegalStateException("本地 admin 用户不存在: " + adminUsername));


            String jwt = tokenProvider.generateToken(
                    new UsernamePasswordAuthenticationToken(admin.getUsername(), null, Collections.emptyList())
            );

            return jwt;
        } catch (IOException e) {
            throw new IllegalStateException("解析第三方响应失败", e);
        }
    }

    /**
     * 调用第三方校验接口并返回响应 body（字符串）。
     * 配置项从 SaasAuthProperties 中获取（saas.auth.*）。
     */
    private String callThirdPartyVerify(String token) {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String randStr = SignUtil.randomStr(16);

        // 根据配置的 encryptionType 生成 sign（和你原来逻辑保持一致）
        String sign = SignUtil.generateSign(props.getAppSecret(), timestamp, randStr, props.getEncryptionType());

        HttpHeaders headers = new HttpHeaders();
        headers.add("appKey", props.getAppKey());
        headers.add("timestamp", timestamp);
        headers.add("randStr", randStr);
        headers.add("sign", sign);
        headers.add("encryptionType", props.getEncryptionType());

        // 请求体
        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
        form.add("token", token);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(form, headers);
        RestTemplate restTemplate = restTemplateBuilder.build();

        // 规范化 baseUrl（去掉末尾斜杠），拼接接口路径
        String base = props.getBaseUrl() == null ? "" : props.getBaseUrl().replaceAll("/+$", "");
        String url = base + "/api/open-api/auth/verify-user";

        logger.debug("Calling external verify url={}, headers=[appKey={}, timestamp={}, randStr={}, encryptionType={}]",
                url, props.getAppKey(), timestamp, randStr, props.getEncryptionType());

        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, request, String.class);

        if (responseEntity == null) {
            logger.error("第三方校验无 ResponseEntity，url={}", url);
            throw new IllegalStateException("第三方校验失败：无响应");
        }

        String body = responseEntity.getBody();
        if (body == null) {
            logger.error("第三方校验返回 body 为空，status={}, headers={}", responseEntity.getStatusCode(), responseEntity.getHeaders());
            throw new IllegalStateException("第三方校验失败：响应体为空");
        }

        logger.debug("第三方校验响应 status={}, body={}", responseEntity.getStatusCodeValue(), body);
        return body;
    }
}
